#include <iostream>
#include <cstdio>
#include <string>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <vector>
#include <assert.h>
#include <time.h>

#include "Tash.hpp"

#define Process_Num 5

int WaitCommand(int fd)
{
    uint32_t wait = 0;
    ssize_t ret = read(fd, &wait, sizeof(wait));
    assert(ret == sizeof(wait));
    (void)ret;

    return wait;
}

void SendCommand(pid_t id, int fd, uint32_t Command)
{
    write(fd, &Command, sizeof(Command));
    std::cout << "main process send to [" << id << "] \t\t execute task: " << des[Command]
              << "\t fd: " << fd << std::endl;
}

int main()
{
    srand((unsigned int)time(nullptr));
    std::vector<std::pair<pid_t, int>> slot;
    Init();
    for (int i = 0; i < Process_Num; i++)
    {
        int pipefd[2] = {0};
        pipe(pipefd);
        pid_t id = fork();
        assert(id != -1);

        if (id == 0)
        {
            // 子进程读取
            close(pipefd[1]);

            while (true)
            {
                int command = WaitCommand(pipefd[0]);
                // 执行命令
                if (command >= 0 && command < HandSize)
                {
                    callback[command]();
                }
                else
                {
                    std::cout << "非法" << std::endl;
                }
            }
            close(pipefd[0]);
        }

        // 父进程写入
        close(pipefd[0]);
        slot.push_back(std::make_pair(id, pipefd[1]));
    }
    while (true)
    {
        // 随机执行命令
        uint32_t task = rand() % HandSize;
        int who = rand() % Process_Num;

        SendCommand(slot[who].first, slot[who].second, task);
        sleep(1);
    }

    for (auto e : slot)
    {
        close(e.second);
    }

    return 0;
}